package com.larry.tinyweb.core.log;

import com.larry.tinyweb.core.Global;
import com.larry.tinyweb.util.DateUtil;
import sun.rmi.runtime.Log;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by larry on 16/12/12.
 * @author larry
 *
 * log打印模式
 * %d 日期，后面{}里跟日期格式
 * %p 日志等级
 * %c 类全路径
 * %n 换行
 * %m 输出代码中指定的消息
 * %t 输出产生该日志事件的线程名
 *
 * level 1-debug 2-info 3-warn 4-error
 */
public class TinyLogger implements Logger {
    private static boolean isWindows = false;
    private String logPattern = "%d{yyyy-MM-dd HH:mm:ss} %p [%c] - %m%n";
    private Class clazz;

    static {
        String os = System.getProperty("os.name");
        if (os.contains("Windows")) isWindows = true;
    }

    public static Logger getLogger(Class clazz) {
        return new TinyLogger(clazz);
    }

    public TinyLogger(Class clazz) {
        this.clazz = clazz;
    }

    public TinyLogger(Class clazz, String logPattern) {
        this.clazz = clazz;
        this.logPattern = logPattern;
    }

    @Override
    public void debug(String logString, Object...args) {
        print(1, logString, args);
    }

    @Override
    public void info(String logString, Object...args) {
        print(2, logString, args);
    }

    @Override
    public void warn(String logString, Object...args) {
        print(3, logString, args);
    }

    @Override
    public void error(String logString, Object...args) {
        print(4, logString, args);
    }

    private void print(Integer level, String logString, Object...args) {
        if (!Global.logUseAble || level < Global.logLevel) return;

        String levelString = getLevelString(level);
        String out = m(t(n(c(p(d(logPattern), levelString)))), logString);
        for (Object obj : args) {
            if (obj == null) break;
            out = out.replaceFirst("\\{\\}", obj.toString());
        }

        System.out.print(out);
    }

    private String getLevelString(Integer level) {
        if (level == 1) return "DEBUG";
        if (level == 2) return "INFO";
        if (level == 3) return "WARN";
        if (level == 4) return "ERROR";
        return "DEBUG";
    }

    private String d(String logPattern) {
        String rex = "%d\\{[\\w :-]+\\}";
        Pattern compile = Pattern.compile(rex);
        Matcher matcher = compile.matcher(logPattern);
        if (matcher.find()) {
            String result = matcher.group();
            String datePattern = result.replaceAll("%d", "").replaceAll("[\\{\\}]", "").trim();
            return logPattern.replaceAll(rex, DateUtil.getTime(datePattern));
        }
        return logPattern;
    }

    private String p(String logPattern, String level) {
        return logPattern.replaceAll("%p", level);
    }

    private String c(String logPattern) {
        return logPattern.replaceAll("%c", clazz.getName());
    }

    private String n(String logPattern) {
        String rn;
        if (isWindows) rn = "\r\n";
        else rn = "\n";
        return logPattern.replaceAll("%n", rn);
    }

    private String t(String logPattern) {
        return logPattern.replaceAll("%t", "ThreadID-" + String.valueOf(Thread.currentThread().getId()));
    }

    private String m(String logPattern, String logString) {
        return logPattern.replaceAll("%m", logString);
    }

}
